package com.renu.jdependencyanalyser.window;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.renu.jdependencyanalyser.core.ProjectInfo;
import com.renu.jdependencyanalyser.data.OuterClsTblData;
import com.renu.jdependencyanalyser.data.ProjectDataCenter;
import com.renu.jdependencyanalyser.data.OuterMthdTblData;
import com.renu.jdependencyanalyser.model.ClassModel;
import com.renu.jdependencyanalyser.model.MethodModel;
import com.renu.jdependencyanalyser.model.PackageModel;
import com.renu.jdependencyanalyser.utils.DataConvert;
import com.renu.jdependencyanalyser.utils.MyProjectUtil;
import com.renu.jdependencyanalyser.window.action.OuterClsDpndcyPseudoAction;
import com.renu.jdependencyanalyser.window.action.OuterMthdDpndcyPseudoAction;
import com.renu.jdependencyanalyser.window.model.OuterClassTableItem;
import com.renu.jdependencyanalyser.window.model.MthodTableItem;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Map;

public class AnalyserWindow {
    private ProjectInfo projectInfo = ProjectDataCenter.projectInfo;

    private JPanel contentPanel;
    private JTable tb_content;
    private JButton bnt_refresh;
    private JTable tb_outerClass;
    private JButton bnt_outerClass;
    private JPanel outerMthodPanel;
    private JPanel outerClassPanel;
    private JTable tb_class;
    private JTable tb_classMthd;
    private JPanel currentProjectPanel;
    private JTextPane txt_outerMethod;
    private JTextPane txt_outerClass;
    private JTable tb_outerLib;
    private JTextPane txt_outerLib;
    private JTextPane txt_classSig;
    private JTable tb_classOuterClass;
    private JTable tb_classBorderMethod;
    private JTextPane txt_classBorderMethod;
    private JTextPane txt_classOuterClass;

    private JPopupMenu outerMthdPopupMenu;
    private JPopupMenu outerClsPopupMenu;
    private JMenuItem showInvokeImage;
    private JMenuItem showDependencyImage;

    //private PanelShow panelShow;

    public AnalyserWindow(Project project, ToolWindow toolWindow) {

        String projectBasePath = project.getBasePath();

        MyProjectUtil.projectBasePath = projectBasePath;

        ProjectDataCenter.asmAnalyse();

        initOuterMthodPanel();
        initOuterClsPanel();
        //panelShow.initOuterLib(tb_outerLib,txt_outerLib);
    }



    private void initOuterMthodPanel() {
        tb_content.setModel(OuterMthdTblData.TABLE_MODEL);
        tb_content.setEnabled(true);
        outerMthdPopupMenu = new JPopupMenu();
        showInvokeImage = new JMenuItem("View Invoke Chain");
        outerMthdPopupMenu.add(showInvokeImage);



        fillContent();
        initBntRefresh();
        initTbConten();
        initShowInvokeChain();


    }
    private void initOuterClsPanel() {
        tb_outerClass.setModel(OuterClsTblData.TABLE_MODEL);
        tb_outerClass.setEnabled(true);
        outerClsPopupMenu = new JPopupMenu();
        showDependencyImage = new JMenuItem("View Dependency Chain");
        outerClsPopupMenu.add(showDependencyImage);



        fillTbOuterClass();
        initBnt_outerClass();
        initTable(tb_outerClass,outerClsPopupMenu);
        initShowOuterDeppendency();

    }

    private void initShowOuterDeppendency() {
        showDependencyImage.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                int selectedRow = tb_outerClass.getSelectedRow();
                if (selectedRow != -1){
                    OuterClassTableItem outerClassTableItem = OuterClsTblData.ITEM_LIST.get(selectedRow);
                    String clsSig = DataConvert.convert2ClsSig(outerClassTableItem);
                    new OuterClsDpndcyPseudoAction(clsSig);
                }
            }
        });
    }

    private void initTable(JTable table, JPopupMenu popupMenu) {
        table.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                showPopup(e);
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                showPopup(e);
            }
            private void showPopup(MouseEvent e) {
                if (e.isPopupTrigger()){
                    popupMenu.show(e.getComponent(),e.getX(),e.getY());
                }
            }
        });
    }

    private void initBnt_outerClass() {
        bnt_outerClass.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                OuterClsTblData.clear();
                ProjectDataCenter.asmAnalyse();
                fillTbOuterClass();
            }
        });
    }

    private void fillTbOuterClass() {
        ProjectInfo projectInfo = ProjectDataCenter.projectInfo;
        Map<String, ClassModel> outerMap =projectInfo.getBorderClassMap();

        for (String key : outerMap.keySet()) {
            ClassModel clsModel = outerMap.get(key);
            String classSig = clsModel.getClsSig();
            PackageModel packageModel = projectInfo.getOuterPckMap().get(clsModel.getPck());
            String jarsig = packageModel.getJarSig();
            int times = clsModel.getSrcClsSig().size();
            OuterClassTableItem outerClassTableItem = new OuterClassTableItem(jarsig,classSig, times);
            OuterClsTblData.ITEM_LIST.add(outerClassTableItem);
            OuterClsTblData.TABLE_MODEL.addRow(DataConvert.convert(outerClassTableItem));

        }

        txt_outerClass.setText("Total："+OuterClsTblData.ITEM_LIST.size());
    }



    private void initShowInvokeChain() {
        showInvokeImage.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                int selectedRow = tb_content.getSelectedRow();
                if (selectedRow != -1){
                    MthodTableItem mthodTableItem = OuterMthdTblData.ITEM_LIST.get(selectedRow);
                    String methodSig = DataConvert.convert2MthdSig(mthodTableItem);
                    new OuterMthdDpndcyPseudoAction(methodSig);
                }
            }
        });

    }

    private void initTbConten() {
        tb_content.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                showPopup(e);
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                showPopup(e);
            }
            private void showPopup(MouseEvent e) {
                if (e.isPopupTrigger()){
                    outerMthdPopupMenu.show(e.getComponent(),e.getX(),e.getY());
                }
            }
        });

    }

    private void initBntRefresh() {
        bnt_refresh.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                OuterMthdTblData.clear();
                ProjectDataCenter.asmAnalyse();
                fillContent();
            }
        });
    }

    private void fillContent() {
        Map<String, MethodModel> outerMethodMap = ProjectDataCenter.projectInfo.getBorderMethodMap();
        for (String key : outerMethodMap.keySet()) {
            MethodModel methodModel = outerMethodMap.get(key);
            String classSig = methodModel.getClassSig();
            String mthdName=  methodModel.getMethodSig().split("\n")[1];
            int times = methodModel.getSrcMethods().size();
            MthodTableItem mthodTableItem = new MthodTableItem(classSig,mthdName,times);
            OuterMthdTblData.ITEM_LIST.add(mthodTableItem);
            OuterMthdTblData.TABLE_MODEL.addRow(DataConvert.convert(mthodTableItem));

        }
        txt_outerMethod.setText("Total："+OuterMthdTblData.ITEM_LIST.size());





    }


    public JPanel getContentPanel() {
        return contentPanel;
    }


    private void createUIComponents() {
        // TODO: place custom component creation code here
    }

    public JTable getTb_class() {
        return tb_class;
    }

    public JTable getTb_classMthd() {
        return tb_classMthd;
    }

    public JTable getTb_outerLib() {
        return tb_outerLib;
    }

    public JTextPane getTxt_outerLib() {
        return txt_outerLib;
    }

    public JTextPane getTxt_classSig() {
        return txt_classSig;
    }

    public JTable getTb_classOuterClass() {
        return tb_classOuterClass;
    }

    public JTable getTb_classBorderMethod() {
        return tb_classBorderMethod;
    }

    public JTextPane getTxt_classBorderMethod() {
        return txt_classBorderMethod;
    }

    public JTextPane getTxt_classOuterClass() {
        return txt_classOuterClass;
    }
}
